package environment;

import java.io.File;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;

import Billing.Billing;
import Client.Client;
import Operator.AggressiveStrategy;
import Operator.DesperateStrategy;
import Operator.Heyah;
import Operator.Operator;
import Operator.OrangeGo;
import Operator.PlayFresh;
import Operator.SimplusTwojProfilDoWszystkich;
import Operator.SimplusTwojProfilPlus;
import Operator.SpecialisedStrategy;
import Operator.Strategy;

public class MarketAgent 
{
	// Agent stuff
	private static Map<String, Operator> operators; // map : names of operators
	private static Map<Client, String> clients; // map : client and its operator
	private static Map<String, Integer> operators_count;
	private Boolean run;
	
	public void initializeData(int nr_of_clients)
	{
		operators = new HashMap<String, Operator>();
		clients = new HashMap<Client, String>();
		operators_count = new HashMap<String, Integer>();
		run = true;

		// TO DO - read all from files from directory
		File dir = new File("billings/");
		String[] oryginal_billings = dir.list();

		// TO DO - other operators
		/*
		 * Operator simplus = new Operator("simplus"); simplus.addPriceList(new
		 * SimplusTwojProfilDoWszystkich("plus")); operators.put("simplus",
		 * simplus);
		 */
		
		Operator orangeGo = new Operator("orange", new Strategy());
		orangeGo.addPriceList(new OrangeGo("orange"));
		operators.put("orange", orangeGo);
		
		Operator simplus2 = new Operator("simplus2", new AggressiveStrategy());
		simplus2.addPriceList(new SimplusTwojProfilDoWszystkich("plus"));
		simplus2.addPriceList(new SimplusTwojProfilPlus("plus"));
		operators.put("simplus2", simplus2);

		Operator playFresh = new Operator("playFresh", new SpecialisedStrategy());
		playFresh.addPriceList(new PlayFresh("playFresh"));
		operators.put("playFresh", playFresh);

		Operator heyah = new Operator("heyah", new DesperateStrategy());
		heyah.addPriceList(new Heyah("heyah"));
		operators.put("heyah", heyah);

		Random r = new Random();
		Integer clients_number = nr_of_clients;
		if (oryginal_billings.length < clients_number)
			clients_number = oryginal_billings.length;

		// TO DO - other operators. Only simplus now.
		Operator[] op_list = new Operator[operators.size()];
		operators.values().toArray(op_list);

		String[] op_names = new String[operators.size()];
		operators.keySet().toArray(op_names);
		for (int i = 0; i < clients_number; i++) 
		{
			if (!oryginal_billings[i].contains(".txt"))
				continue;

			Client newClient = new Client("user" + Integer.toString(i),
					"billings/" + oryginal_billings[i], r.nextDouble(), 1 + r.nextInt(10), op_names);
			Integer op = r.nextInt(operators.keySet().size());
			op_list[op].addClient(newClient);
			newClient.setOperatorName(op_list[op].getName());
			clients.put(newClient, op_list[op].getName());
		}
		
		for (String op : operators.keySet())
		{
			operators_count.put(op, operators.get(op).getClientCount());
		}
	}
	

	public Map<String, Integer> getOperatorsCount()
	{
		return operators_count;
	}
		
	public void switchRun()
	{
		run = !run;
	}
	
	public int getClientsSize()
	{
		return clients.size();
	}
	
	public Map<String, Operator> getOperators()
	{
		return operators;
	}
	
	public void doMonthOperations()
	{
		Billing bl;
		Map<String, Double> prices = new HashMap<String, Double>();
		String selected_name;
		String old_operator;
		String[] cl_list = new String[clients.size()];
		
		clients.values().toArray(cl_list);
		for (Client cl : clients.keySet()) 
		{
			while(!run)
			{
				try {
					Thread.sleep(200);
				} 
				catch (InterruptedException e1) 
				{
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
			}
			
			IO.clientPrint("\nRozpatrujemy klienta: " + cl.getName(), IO.DEBUG);
			bl = cl.getBilling(cl_list);
			prices.clear();

			for (String name : operators.keySet())
				prices.put(name, operators.get(name).countPrice(bl));

			IO.clientPrint(prices.toString(), IO.DEBUG);
			selected_name = cl.selectOperator(prices);
			old_operator = clients.get(cl);

			IO.clientPrint("Klient wybrał sieć: " + selected_name, IO.DEBUG);
			if (!selected_name.equals(old_operator)) 
			{
				IO.clientPrint( cl.getName() + " zmienł sieć na " + selected_name,
						IO.INFO);
				operators.get(old_operator).removeClient(cl);
				operators.get(selected_name).addClient(cl);
				clients.put(cl, selected_name);
			}
		}
		
		operators_count.clear();
		for (String op : operators.keySet())
		{
			operators_count.put(op, operators.get(op).getClientCount());
		}
	}
}
